/*******************************************************************************
* Project: QSAR(Cute Software Architecture) 
*
* Copyright: Copyright(C) 2024 by YuetingBen, All Rights Reserved
*
* File name: DcmDspSvc2E.c
*
* Brief: ;
*
* Author: Yueting.Ben
*
* Module: Dcm
*
* Revision:
* --------------------------------------------------------------------------------
* v0.1: 
* --Yueting.Ben, 2024-03-21 
* --Initial release

**********************************************************************************/

/** HEADER FILES **/
#include "DcmDspSvc2E.h"
#include "DcmDspDidType.h"
#include "DcmDspDidCfg.h"
#include "DcmDspDid.h"
#include "DcmDsp.h"


/** MACRO DEFINITION **/
#define DCM_PROGRESS_DID_CHECK ((Dcm_ProgressType)0x10u)
#define DCM_PROGRESS_ACCESS_CHECK ((Dcm_ProgressType)0x11u)
#define DCM_PROGRESS_WRITE ((Dcm_ProgressType)0x12u)


/** TYPEDEF DEFINITION **/


/** LOCAL DATA DECLARATION **/


/** GLOBAL DATA DECLARATION **/


/** LOCAL FUNCTION DECLARATION **/


/** GLOBAL FUNCTION DECLARATION **/
Std_ReturnType DcmDsp_Svc2E_Processor(
    Dcm_ExtendedOpStatusType OpStatus,
    Dcm_MsgContextType* pMsgContext,
    Dcm_NegativeResponseCodeType* ErrorCode
);

/** LOCAL DATA **/


/** GLOBAL DATA **/


/** LOCAL FUNCTION **/


/** GLOBAL FUNCTION **/
Std_ReturnType DcmDsp_Svc2E_Processor(
    Dcm_ExtendedOpStatusType OpStatus,
    Dcm_MsgContextType* pMsgContext,
    Dcm_NegativeResponseCodeType* ErrorCode
)
{
    Std_ReturnType retVal = E_NOT_OK;
    DcmDspDidIdentifierType did;
    DcmDspDidInfoType* didInfoPtr;
    static DcmDspDidIndexType didIndex;
    DcmDspDidSignalIndexType signalIndex;
    Dcm_SesCtrlType sesCtrl;
    Dcm_SecLevelType secLevel;
    
    switch(Dcm_GetProgress(pMsgContext))
    {
        case DCM_PROGRESS_INITIAL:
        {
            retVal = DCM_E_PENDING;
            Dcm_SetProgress(pMsgContext, DCM_PROGRESS_DID_CHECK);
            break;
        }
        case DCM_PROGRESS_DID_CHECK:
        {
            did = (DcmDspDidIdentifierType)(((DcmDspDidIdentifierType)pMsgContext->reqData[DCM_REQ_DATA_DID_HIGH_INDEX] << 8) + pMsgContext->reqData[DCM_REQ_DATA_DID_LOW_INDEX]);

            *ErrorCode = DCM_E_REQUESTOUTOFRANGE;
            for(didIndex = DCM_DSP_DID_INDEX_FIRST; didIndex < DCM_DSP_DID_INDEX_MAX; didIndex++)
            {
                didInfoPtr = (DcmDspDidInfoType*)(&DcmDspDidInfoCfg[didIndex]);
                if(did == didInfoPtr->did)
                {
                    Dcm_SetProgress(pMsgContext, DCM_PROGRESS_ACCESS_CHECK);
                    retVal = DCM_E_PENDING;
                    break;
                }
            }
            break;
        }
        case DCM_PROGRESS_ACCESS_CHECK:
        {
            didInfoPtr = (DcmDspDidInfoType*)(&DcmDspDidInfoCfg[didIndex]);
            retVal = DcmDsp_SessionCheck((DcmDspSessionType*)&didInfoPtr->writeAccess.didWriteSessionLevel);
            if(E_OK == retVal)
            {
                retVal = DcmDsp_SecurityCheck((DcmDspSessionType*)&didInfoPtr->writeAccess.didWriteSecurityLevel);
                if(E_OK == retVal)
                {
                    retVal = DCM_E_PENDING;
                    Dcm_SetProgress(pMsgContext, DCM_PROGRESS_WRITE);
                }
                else
                {
                    *ErrorCode = DCM_E_SECURITYACCESSDENIED;
                }
            }
            else
            {
                *ErrorCode = DCM_E_REQUESTOUTOFRANGE;
            }  
            break;
        }
        case DCM_PROGRESS_WRITE:
        {
            didInfoPtr = (DcmDspDidInfoType*)(&DcmDspDidInfoCfg[didIndex]);
            for(signalIndex = 0u; signalIndex < (didInfoPtr->signalNum); signalIndex++)
            {
                if(DCM_NULL_PROCESSOR != didInfoPtr->signalPtr[signalIndex].didDataPtr->dataWriteFnc)
                {
                    pMsgContext->resDataLen = 2;
                    retVal = didInfoPtr->signalPtr[signalIndex].didDataPtr->dataWriteFnc(&pMsgContext->reqData[DCM_RES_DATA_START_INDEX + didInfoPtr->signalPtr[signalIndex].didByteOffset]);
                }
            }
            break;
        }
        default:
        {
            *ErrorCode = DCM_E_REQUESTOUTOFRANGE;
            break;
        }
    }
    
#if 0
    did = (DcmDspDidIdentifierType)(((DcmDspDidIdentifierType)pMsgContext->reqData[DCM_REQ_DATA_DID_HIGH_INDEX] << 8) + pMsgContext->reqData[DCM_REQ_DATA_DID_LOW_INDEX]);

    *ErrorCode = DCM_E_REQUESTOUTOFRANGE;
    for(didIndex = DCM_DSP_DID_INDEX_FIRST; didIndex < DCM_DSP_DID_INDEX_MAX; didIndex++)
    {
        didInfoPtr = (DcmDspDidInfoType*)(&DcmDspDidInfoCfg[didIndex]);
        if(did == didInfoPtr->did)
        {
            if(didInfoPtr->writeAccess.sessionAccess != (didInfoPtr->writeAccess.sessionAccess & sesCtrl))
            {
                *ErrorCode = DCM_E_SERVICENOTSUPPORTEDINACTIVESESSION;
            }
            else if(didInfoPtr->writeAccess.securityAccess != (didInfoPtr->writeAccess.securityAccess & secLevel))
            {
                *ErrorCode = DCM_E_SECURITYACCESSDENIED;
            }
            else
            {
                for(signalIndex = 0u; signalIndex < (didInfoPtr->signalNum); signalIndex++)
                {
                    if(DCM_NULL_PROCESSOR != didInfoPtr->signalPtr[signalIndex].didDataPtr->dataWriteFnc)
                    {
                        pMsgContext->resDataLen = 2;
                        retVal = didInfoPtr->signalPtr[signalIndex].didDataPtr->dataWriteFnc(&pMsgContext->reqData[DCM_RES_DATA_START_INDEX + didInfoPtr->signalPtr[signalIndex].didByteOffset]);
                    }
                }
            }

            break;
        }
    }
#endif
    return(retVal);
}

